const Exchange = artifacts.require("Exchange");
const MyToken = artifacts.require("MyToken");

contract("Exchange", (accounts) => {
  // 模拟三个地址：exchange交易所，alice、bob为用户
  let [exchange, alice, bob, feeAccount] = accounts;
  let exchangeContract, tokenContract;

  beforeEach(async () => {
    exchangeContract = await Exchange.new(feeAccount, 10, { from: exchange });
    tokenContract = await MyToken.new("WarrickToken", "WKT", { from: alice });
    // 将10,0000代币授权给交易所
    await tokenContract.approve(
      exchangeContract.address,
      web3.utils.toWei("100000", "ether"),
      {
        from: alice,
      }
    );
  });

  context("WKT token management", async () => {
    beforeEach(async () => {
      await exchangeContract.depositToken(
        tokenContract.address,
        web3.utils.toWei("100000", "ether"),
        {
          from: alice,
        }
      );
    });

    it("deposit 100000 WKT to exchange", async () => {
      const balance = await exchangeContract.balanceOf(tokenContract.address, {
        from: alice,
      });
      assert.equal(web3.utils.fromWei(balance, "ether"), 100000);
    });

    it("withdraw 10000 WKT after deposit 100000 WKT to exchange", async () => {
      await exchangeContract.withdrawToken(
        tokenContract.address,
        web3.utils.toWei("10000", "ether"),
        {
          from: alice,
        }
      );
      const balance = await tokenContract.balanceOf(alice);
      assert.equal(web3.utils.fromWei(balance, "ether"), 910000);
    });
  });

  context("ether management", async () => {
    let depositEtherRes;

    beforeEach(async () => {
      depositEtherRes = await exchangeContract.depositEther({
        from: bob,
        value: web3.utils.toWei("100", "ether"),
      });
    });

    it("deposit 100 ether to exchange", async () => {
      assert.equal(depositEtherRes.receipt.status, true);
      assert.equal(
        web3.utils.fromWei(depositEtherRes.logs[0].args._value, "ether"),
        100
      );
    });

    it("withdraw 10 ether after deposit 100 ether to exchange", async () => {
      const result = await exchangeContract.withdrawEther(
        web3.utils.toWei("10", "ether"),
        {
          from: bob,
        }
      );
      assert.equal(web3.utils.fromWei(result.logs[0].args._value, "ether"), 10);
      const ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
      const balance = await exchangeContract.balanceOf(ETH_ADDRESS, {
        from: bob,
      });
      assert.equal(web3.utils.fromWei(balance, "ether"), 90);
    });
  });
});
